package cn.flightcloud.cloud.security.config;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Objects;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;

//@Configuration
//@EnableAuthorizationServer
//@Order(89)
public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {
	@Autowired
	private ApplicationContext applicationContext;
	@Autowired
	private TokenStore tokenStore;
	@Autowired
	private AuthenticationManager authenticationManager;
	@Autowired
	private UserDetailsService userDetailsService;
	@Autowired(required = false)
	private JdbcClientDetailsService jdbcClientDetailsService;
	@Autowired
	private DataSource dataSource;


	/**
	 * 令牌存储
	 * 
	 * @param dataSource 数据源
	 * @return
	 */
	@Bean
	public TokenStore tokenStore() {
		return new JdbcTokenStore(dataSource);
	}

	/**
	 * 配置授权服务器端点，如令牌存储，令牌自定义，用户批准和授权类型，不包括端点安全配置
	 * 
	 * @param endpoints
	 * @throws Exception
	 */
	@Override
	public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
		Collection<TokenEnhancer> tokenEnhancers = applicationContext.getBeansOfType(TokenEnhancer.class).values();
		TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
		tokenEnhancerChain.setTokenEnhancers(new ArrayList<>(tokenEnhancers));

		DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
//		defaultTokenServices.setReuseRefreshToken(isReuseRefreshToken);
//		defaultTokenServices.setSupportRefreshToken(isSupportRefreshToken);
		defaultTokenServices.setTokenStore(tokenStore);
//		defaultTokenServices.setAccessTokenValiditySeconds(accessTokenValiditySeconds);
//		defaultTokenServices.setRefreshTokenValiditySeconds(refreshTokenValiditySeconds);
		defaultTokenServices.setTokenEnhancer(tokenEnhancerChain);
		// 若通过 JDBC 存储令牌
		if (Objects.nonNull(jdbcClientDetailsService)) {
			defaultTokenServices.setClientDetailsService(jdbcClientDetailsService);
		}

		endpoints.authenticationManager(authenticationManager).userDetailsService(userDetailsService)
				.tokenServices(defaultTokenServices);
	}

	/**
	 * 配置授权服务器端点的安全
	 * 
	 * @param oauthServer
	 * @throws Exception
	 */
	@Override
	public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
		oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("permitAll()").allowFormAuthenticationForClients();
	}
}
